package org.jsola.hr.provider.impl;

import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.entity.CompanySaleServerDO;
import org.jsola.hr.provider.INoticeProviderService;
import org.jsola.hr.service.ICompanySaleServerService;
import org.jsola.notice.constant.NoticeConstants;
import org.jsola.notice.constant.WayType;
import org.jsola.notice.dto.*;
import org.jsola.notice.entity.NoticeGroupDO;
import org.jsola.notice.entity.NoticeRuleSettingDO;
import org.jsola.notice.service.*;
import org.jsola.notice.vo.NoticeGroupListVO;
import org.jsola.notice.vo.NoticeGroupVO;
import org.jsola.notice.vo.NoticeRuleSettingVO;
import org.jsola.notice.vo.NoticeTypeVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import static org.jsola.hr.constant.HrPermissionConstants.COMPANY_SUBJECT_TYPE;
import static org.jsola.hr.constant.HrPermissionConstants.HR_SUBJECT_TYPE;

/**
 * @author zxy
 */
@Service("hrNoticeProviderService")
public class NoticeProviderServiceImpl implements INoticeProviderService {

    @Value("${spring.application.name}")
    private String appName;

    @Autowired
    private INoticeGroupService noticeGroupService;

    @Autowired
    private INoticeTypeService noticeTypeService;

    @Autowired
    private IUserNoticeService userNoticeService;

    @Autowired
    private INoticeRuleSettingService noticeRuleSettingService;

    @Autowired
    private INoticeInitService noticeInitService;

    @Autowired
    private ICompanySaleServerService companySaleServerService;

    /**
     * 跳转地址-签署记录
     */
    private static final String TO_URL_CONTRACT = "/contract/elecontract";


    @Override
    public void memoRemindNoticeSend(String companyId, String content, String companyName, TokenUser tokenUser) {
        // 备忘录提醒通知类型是否存在
        NoticeTypeVO noticeTypeVO = noticeTypeService.selectByCode(HrConstants.HR_SUBJECT_TYPE, HrConstants.NOTICE_TYPE_CODE_MEMO_REMIND, HrConstants.DEFAULT);
        if (Objects.isNull(noticeTypeVO)) {
            // 新增通知分类
            NoticeGroupAddDTO noticeGroupAddDTO = new NoticeGroupAddDTO();
            noticeGroupAddDTO.setName("备忘提醒");
            noticeGroupAddDTO.setDesc("备忘提醒消息通知");
            noticeGroupAddDTO.setModuleType(HrConstants.HR_SUBJECT_TYPE);
            noticeGroupAddDTO.setParentId((long) 0);
            NoticeGroupVO noticeGroup = noticeGroupService.save(noticeGroupAddDTO, tokenUser);

            // 新增通知方式
            NoticeTypeAddDTO noticeTypeAddDTO = new NoticeTypeAddDTO();
            noticeTypeAddDTO.setCode(HrConstants.NOTICE_TYPE_CODE_MEMO_REMIND);
            noticeTypeAddDTO.setNoticeGroupId(noticeGroup.getId());
            noticeTypeAddDTO.setName("备忘提醒");
            noticeTypeAddDTO.setDesc("备忘提醒消息通知");
            noticeTypeService.save(noticeTypeAddDTO, tokenUser);
        }
        UserNoticeAddDTO userNoticeAddDTO = new UserNoticeAddDTO();
        userNoticeAddDTO.setUserId(tokenUser.getUserId());
        userNoticeAddDTO.setModuleType(HrConstants.HR_SUBJECT_TYPE);
        userNoticeAddDTO.setNoticeTypeId(noticeTypeVO.getId());
        userNoticeAddDTO.setNoticeTypeCode(HrConstants.NOTICE_TYPE_CODE_MEMO_REMIND);
        userNoticeAddDTO.setWayType(WayType.WEIXIN.getValue());
        userNoticeAddDTO.setTitle("备忘提醒消息通知");
        userNoticeAddDTO.setContent(content);
        userNoticeAddDTO.setToUrl("");
        userNoticeAddDTO.setSubjectType(COMPANY_SUBJECT_TYPE);
        userNoticeAddDTO.setSubjectId(companyId);
        userNoticeAddDTO.setCompanyName(companyName);
        userNoticeAddDTO.setCreateUserName("系统");

        userNoticeService.saveByCode(userNoticeAddDTO, HrConstants.HR_SUBJECT_TYPE, HrConstants.NOTICE_TYPE_CODE_MEMO_REMIND, tokenUser);
    }

    @Override
    public void empSignOverNoticeSend(String companyId, String userId, String content, String companyName, TokenUser tokenUser) {

        // 备忘录提醒通知类型是否存在
        NoticeTypeVO noticeTypeVO = noticeTypeService.selectByCode(HrConstants.HR_SUBJECT_TYPE
                , HrConstants.NOTICE_TYPE_CODE_EMP_SIGN_OVER, HrConstants.DEFAULT);
        if (Objects.isNull(noticeTypeVO)) {
            // 新增通知分类
            NoticeGroupAddDTO noticeGroupAddDTO = new NoticeGroupAddDTO();
            noticeGroupAddDTO.setName("合同员工签署成功");
            noticeGroupAddDTO.setDesc("合同员工签署成功提醒");
            noticeGroupAddDTO.setModuleType(HrConstants.HR_SUBJECT_TYPE);
            noticeGroupAddDTO.setParentId((long) 0);
            NoticeGroupVO noticeGroup = noticeGroupService.save(noticeGroupAddDTO, tokenUser);

            // 新增通知方式
            NoticeTypeAddDTO noticeTypeAddDTO = new NoticeTypeAddDTO();
            noticeTypeAddDTO.setCode(HrConstants.NOTICE_TYPE_CODE_EMP_SIGN_OVER);
            noticeTypeAddDTO.setNoticeGroupId(noticeGroup.getId());
            noticeTypeAddDTO.setName("合同员工签署成功");
            noticeTypeAddDTO.setDesc("合同员工签署成功提醒");
            noticeTypeService.save(noticeTypeAddDTO, tokenUser);
        }

        UserNoticeAddDTO userNoticeAddDTO = new UserNoticeAddDTO();
        userNoticeAddDTO.setUserId(userId);
        userNoticeAddDTO.setModuleType(HrConstants.HR_SUBJECT_TYPE);
        userNoticeAddDTO.setNoticeTypeId(noticeTypeVO.getId());
        userNoticeAddDTO.setNoticeTypeCode(HrConstants.NOTICE_TYPE_CODE_EMP_SIGN_OVER);
        userNoticeAddDTO.setWayType(WayType.WEIXIN.getValue());
        userNoticeAddDTO.setTitle("合同员工签署成功提醒");
        userNoticeAddDTO.setContent(content);
        userNoticeAddDTO.setToUrl(TO_URL_CONTRACT + "?immediatelyMaturityCountId=3");
        userNoticeAddDTO.setSubjectType(COMPANY_SUBJECT_TYPE);
        userNoticeAddDTO.setSubjectId(companyId);
        userNoticeAddDTO.setCompanyName(companyName);
        userNoticeAddDTO.setCreateUserName("系统");

        userNoticeService.saveByCode(userNoticeAddDTO, HrConstants.HR_SUBJECT_TYPE, HrConstants.NOTICE_TYPE_CODE_EMP_SIGN_OVER, tokenUser);
    }

    @Override
    public List<NoticeGroupListVO> listAllByCompanyId(String companyId, String moduleType, TokenUser tokenUser) {
        return noticeGroupService.listAllByCompanyId(companyId, moduleType, tokenUser.getSiteId());
    }

    @Override
    public List<NoticeGroupListVO> listAll(String moduleType) {
        return noticeGroupService.listAll(moduleType);
    }

    @Override
    public List<NoticeTypeVO> listTypeByGroupId(String moduleType, Long groupId) {
        return noticeTypeService.selectByGroupIds(Collections.singletonList(groupId), moduleType);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public NoticeRuleSettingVO save(NoticeRuleSettingAddDTO noticeRuleSettingAddDTO, TokenUser tokenUser) {
        return noticeRuleSettingService.save(noticeRuleSettingAddDTO, tokenUser);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(NoticeRuleSettingUpdateDTO noticeRuleSettingUpdateDTO, TokenUser tokenUser) {
        int update = noticeRuleSettingService.update(noticeRuleSettingUpdateDTO, tokenUser);
        if(NoticeConstants.JF_CONTRACT.equals(noticeRuleSettingUpdateDTO.getNoticeTypeCode())){
            List<CompanySaleServerDO> companyServerList = companySaleServerService
                    .selectCompanyServerList(noticeRuleSettingUpdateDTO.getCompanyId(), tokenUser.getSiteId());
            companySaleServerService.addServetTask(companyServerList, noticeRuleSettingUpdateDTO.getCompanyId(), tokenUser);
        }
        return update;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int openNoticeRuleSetting(Long id, TokenUser tokenUser) {
        return noticeRuleSettingService.open(id, tokenUser);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int closeNoticeRuleSetting(Long id, TokenUser tokenUser) {
        return noticeRuleSettingService.close(id, tokenUser);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void initNoticeRuleSettingByCompanyId(List<String> userIdList, String moduleType, String companyId, TokenUser tokenUser) {
        noticeInitService.initNoticeRuleSettingByCompanyId(userIdList, moduleType, companyId, tokenUser);
    }

    @Override
    public NoticeRuleSettingVO selectByTypeCodeAndCompany(String moduleType, Long noticeTypeId, String companyId) {
        //查询公司指定类型id的通知设置
        return noticeRuleSettingService.selectByTypeAndCompany(moduleType, noticeTypeId, companyId);
    }

    @Override
    public NoticeRuleSettingVO selectByTypeCodeAndCompany(String moduleType, String noticeTypeCode, String companyId) {
        //查询公司指定类型code的通知设置
        return noticeRuleSettingService.selectByTypeCodeAndCompany(moduleType, noticeTypeCode, companyId);
    }

    @Override
    public boolean isOpen(String moduleType, String noticeTypeCode, String companyId) {
        NoticeRuleSettingVO noticeRuleSettingVO = noticeRuleSettingService.selectByTypeCodeAndCompany(moduleType, noticeTypeCode, companyId);
        if (Objects.isNull(noticeRuleSettingVO)) {
            return false;
        }
        return noticeRuleSettingVO.getEnableStatus();
    }

    @Override
    public List<NoticeRuleSettingDO> listByNoticeTypeCode(String noticeTypeCode) {
        return noticeRuleSettingService.listByNoticeTypeCode(noticeTypeCode);
    }

    @Override
    public List<NoticeRuleSettingDO> listByCompanyIdAndNoticeTypeCode(String companyId, String noticeTypeCode) {
        return noticeRuleSettingService.listByCompanyIdAndNoticeTypeCode(companyId, noticeTypeCode);
    }

    @Override
    public List<NoticeRuleSettingDO> selectByUserId(String moduleType, String noticeTypeCode, String userId) {
        return noticeRuleSettingService.selectByUserId(moduleType, noticeTypeCode, userId);
    }

    @Override
    public List<NoticeRuleSettingDO> selectByCompanyIdList(String moduleType, String noticeTypeCode,
                                                           List<String> companyIdList) {
        if(CollectionUtils.isEmpty(companyIdList)){
            return new ArrayList<>();
        }
        return noticeRuleSettingService.selectByCompanyIdList(moduleType, noticeTypeCode, companyIdList);
    }

    @Override
    public void saveByCode(UserNoticeAddDTO userNoticeAddDTO, String noticeTypeCode, TokenUser tokenUser) {
        userNoticeService.saveByCode(userNoticeAddDTO, HR_SUBJECT_TYPE, noticeTypeCode, tokenUser);
    }

    @Override
    public void batchSaveByCode(List<UserNoticeAddDTO> userNoticeAddList, Long noticeTypeId, TokenUser tokenUser) {
        userNoticeService.batchSaveById(userNoticeAddList, noticeTypeId, tokenUser);
    }

    @Override
    public NoticeGroupDO selectGroupByName(String name) {
        return noticeGroupService.selectGroupByName(name);
    }

    @Override
    public int selectUserCountByTypeOrGroup(Long groupId, Long typeId, Boolean read, TokenUser tokenUser) {
        return userNoticeService.selectUserCountByTypeOrGroup(groupId, typeId, read, tokenUser);
    }
}
